package top.xierongsheng.utlis.data;

import java.util.Random;
import java.util.UUID;

/**
 * 随机数工具类
 *
 * @auther 谢荣生
 * @datetime 2020/10/23 9:51
 */
public class RandomUtil {

    private static final Random RANDOM = new Random();

    /**
     * main
     *
     * @param args
     */
    public static void main(String[] args) {

    }

    /**
     * 获取32位的UUID(小写)
     *
     * @return
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "").toLowerCase();
    }

    /**
     * 获取随机数字
     *
     * @param bound
     * @return
     */
    public static int nextInt(int bound) {
        return RANDOM.nextInt(bound);
    }

    /**
     * 获取随机数字字符
     *
     * @return
     */
    public static char getNumber() {
        int unicode = RANDOM.nextInt(10) + 48;
        return (char) unicode;
    }

    /**
     * 获取指定长度的随机数字字符串
     *
     * @param length
     * @return
     */
    public static String getNumbers(int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(getNumber());
        }

        return sb.toString();
    }

    /**
     * 获取随机大写字母字符
     *
     * @return
     */
    public static char getLetterUpper() {
        int unicode = RANDOM.nextInt(26) + 65;
        return (char) unicode;
    }

    /**
     * 获取随机小写字母字符
     *
     * @return
     */
    public static char getLetterLower() {
        int unicode = RANDOM.nextInt(26) + 97;
        return (char) unicode;
    }

    /**
     * 获取随机字母字符
     *
     * @return
     */
    public static char getLetter() {
        int flag = RANDOM.nextInt(2);
        if (flag == 0) return getLetterUpper();

        return getLetterLower();
    }

    /**
     * 获取指定长度的随机字母字符串
     *
     * @param length
     * @return
     */
    public static String getLetters(int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(getLetter());
        }

        return sb.toString();
    }

    /**
     * 获取随机数字or小写字母or大写字母
     *
     * @return
     */
    public static char getChar() {
        int flag = RANDOM.nextInt(3);
        if (flag == 0) return getLetterUpper();
        else if (flag == 1) return getLetterLower();

        return getNumber();
    }

    /**
     * 获取指定长度的随机数字or字母字符串
     *
     * @param length
     * @return
     */
    public static String getString(int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(getChar());
        }

        return sb.toString();
    }

    /**
     * 根据给定的字符串获取随机字符
     *
     * @param str
     * @return
     */
    public static char getCharByStr(String str) {
        int index = RANDOM.nextInt(str.length());
        return str.charAt(index);
    }

    /**
     * 根据给定的字符串和指定长度获取随机字符串
     *
     * @param str
     * @param length
     * @return
     */
    public static String getStringByStr(String str, int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(str.charAt(RANDOM.nextInt(str.length())));
        }
        return sb.toString();
    }

    /**
     * 根据给定的字符串和指定长度获取随机字符串（字符在字符串中的顺序不重复）
     * 实现逻辑：
     * 将字符串转换成字符数组，第一次在数组间随机，选取随机字符添加到字符串中，将字符数组最后一个字符的值赋给被选取的字符；
     * 第二次在数组间随机时，不随机数组中最后一个字符，选取随机字符添加到字符串中后，将数组中最后一个字符之前的字符赋值给被选取的字符；
     * 第三次在数组间随机时，不随机数组中最后两个字符，其他同上；
     * 重复如上步骤直到选出所有字符为止。
     *
     * @throws Exception
     */
    public static String getStringByStrNoRepeat(String str, int length) {
        char[] chars = str.toCharArray();
        int cLength = chars.length < length ? chars.length : length;
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int index = RANDOM.nextInt(cLength);
            sb.append(chars[index]);
            chars[index] = chars[cLength - 1];
            cLength -= 1;
        }

        return sb.toString();
    }

}
